#!/usr/bin/perl

use Mojolicious::Lite;

my $users = {};
my @confirms = ();
my @results = ();

websocket '/echo' => sub {
	my $self = shift;
	$self->receive_message(
		sub {
			my ( $self, $message ) = @_;
			$self->send_message($message);
		}
	);
};

websocket '/player' => sub {
	my $self = shift;
	my $uid  = "$self";
	$users->{$uid}->{controller} = $self;
	$users->{$uid}->{is_player}  = 1;
	$self->receive_message(
		sub {
			my ( $self, $message ) = @_;
			my @responses;
			if ( $message =~ m/^name:(.+)$/ ) {
				$users->{$uid}->{name} = $1;
			}
			app->log->debug( 'player message received from ' . $users->{$uid}->{name} . ': ' . $message );
			if ( $message =~ m/^action:(.+)$/ ) {
				my $action = $1;
				if ( $action eq 'start' ) {
					push(@responses, 'set_state: { name : "competition" }');
				}
				elsif ( $action eq 'ready' ) {
					push(@responses, 'set_state: { name : "confirm" }');
					if ( !$users->{$uid}->{confirmed} ) {
						push(@confirms, $uid);
						$users->{$uid}->{confirmed} = scalar @confirms;
						my $response = '';
						foreach my $uid ( sort keys %{$users} ) {
							next unless $users->{$uid}->{is_player};
							$response .= $users->{$uid}->{name} . ': ' . 
							( $users->{$uid}->{confirmed} ? 'Ready!' : 'Waiting...' )
							. '<br />';
						}
						push(@responses, 'set_confirmed : "' . $response . '"');
					}
				}
				elsif ( $action =~ m/^answer=(\d+)$/ ) {
					my $miliseconds = $1;
					push(@responses, 'set_state: { name : "competition" }');
					if ( !$users->{$uid}->{answered} ) {
						push(@results, $uid);
						$users->{$uid}->{answered} = $miliseconds;
						my $response = '';
						my $i = 1;
						foreach my $result_uid ( @results ) {
							$response .= ($i++) . '. ' . $users->{$result_uid}->{name}
							. ' <span class=\"seconds\">(' . ($users->{$result_uid}->{answered} / 1000) . ' seconds)</span>'
							 . '<br />';
						}
						push(@responses, '"set_results" : "' . $response . '"');
					}
				}
			}
			push(@responses, 'set_user_count : ' . scalar keys %{$users} );
			foreach my $uid ( keys %{$users} ) {
				$users->{$uid}->{controller}->send_message( '{' . join(',', @responses) . '}' );
			}
		}
	);
	$self->finished(
		sub {
			delete $users->{$uid};
			foreach my $uid ( keys %{$users} ) {
				$users->{$uid}->{controller}->send_message( '{set_user_count : ' . ( scalar keys %{$users} ) . '}' );
			}
		}
	);
};

websocket '/admin' => sub {
	my $self = shift;
	my $uid  = "$self";
	$users->{$uid}->{controller} = $self;
	$self->receive_message(
		sub {
			my ( $self, $message ) = @_;
			my @responses;
			if ( $message =~ m/^name:(.+)$/ ) {
				$users->{$uid}->{name} = $1;
			}
			app->log->debug( 'admin message received from ' . $users->{$uid}->{name} . ': ' . $message );
			if ( $message =~ m/^action:(.+)$/ ) {
				my $action = $1;
				if ( $action eq 'start' ) {
					push(@responses, 'set_state: { name : "competition" }');
					push(@responses, 'set_results : "waiting..."');
				}
				elsif ( $action eq 'confirm' ) {
					# Clear past results
					@confirms = ();
					@results = ();
					foreach my $uid ( keys %{$users} ) {
						delete $users->{$uid}->{confirmed};
						delete $users->{$uid}->{answered};
					}
					push(@responses, 'set_state: { name : "confirm" }');
					my $response = '';
					foreach my $uid ( sort keys %{$users} ) {
						next unless $users->{$uid}->{is_player};
						$response .= $users->{$uid}->{name} . ': ' . 
						( $users->{$uid}->{confirmed} ? 'Ready!' : 'Waiting...' )
						. '<br />';
					}
					push(@responses, 'set_confirmed : "' . $response . '"');
				}
			}
			push(@responses, 'set_user_count : ' . scalar keys %{$users} );
			foreach my $uid ( keys %{$users} ) {
				$users->{$uid}->{controller}->send_message( '{' . join(',', @responses) . '}' );
			}
		}
	);
	$self->finished(
		sub {
			delete $users->{$uid};
			foreach my $uid ( keys %{$users} ) {
				$users->{$uid}->{controller}->send_message( '{set_user_count : ' . ( scalar keys %{$users} ) . '}' );
			}
		}
	);
};

websocket '/presenter' => sub {
	my $self = shift;
	my $uid  = "$self";
	$users->{$uid}->{controller} = $self;
	$self->receive_message(
		sub {
			my ( $self, $message ) = @_;
			my @responses;
			if ( $message =~ m/^name:(.+)$/ ) {
				$users->{$uid}->{name} = $1;
			}
			push(@responses, 'set_user_count : ' . scalar keys %{$users} );
			foreach my $uid ( keys %{$users} ) {
				$users->{$uid}->{controller}->send_message( '{' . join(',', @responses) . '}' );
			}
		}
	);
	$self->finished(
		sub {
			delete $users->{$uid};
			foreach my $uid ( keys %{$users} ) {
				$users->{$uid}->{controller}->send_message( '{set_user_count : ' . ( scalar keys %{$users} ) . '}' );
			}
		}
	);
};

get '/' => sub {
	my $self = shift;

	$self->render('game');
};

post '/admin' => sub {
	my $self = shift;

	$self->render(
		template => 'admin',
		success  => ( $self->param('password') eq '4dm1n!' ? 1 : 0 )
	);
};

app->start;

__DATA__
@@ admin.html.ep
{ "success" : <%= $success %> }

@@ game.html.ep
<!DOCTYPE html>
<html>
	<head>
		<title>Math Quiz Bowl</title>
		<!-- <link href="http://fonts.googleapis.com/css?family=Reenie+Beanie&subset=latin" rel="stylesheet" type="text/css"> -->
		<link href="css/screen.css" rel="stylesheet" type="text/css">
		<link href="css/buttons.css" rel="stylesheet" type="text/css">
		<link href="css/main.css" rel="stylesheet" type="text/css">
		<script src="js/jquery-1.4.2.min.js"></script>
		<script src="js/jquery.hotkeys.js"></script>
		<script src="js/jquery.cookie.js"></script>
		<script src="js/Base.js"></script>
		<script src="js/buzzer.js"></script>
	</head>
	<body>
		<h1>Math Quiz Bowl Buzzer</h1>
		<hr />
		<div id="tests_failed" class="hide">
			<p>This browser does not appear to meet the minimum requirements.</p>
			<p>Please try another browser, like <a target="_blank" href="http://www.google.com/chrome">Google Chrome</a>, and try again.</p>
		</div>
		<div id="login" class="hide">
			<p>Start by entering your name and choosing a Role.</p>
			<dl>
				<dt>Name:</dt>
				<dd><input type="text" id="user_name" value="" /></dd>
				<dt>Role:</dt>
				<dd>
					<button value="player" class="user_type thoughtbot">Player</button>
					<button value="presenter" class="user_type thoughtbot">Presenter</button>
				</dd>
			</dl>
		</div>
		<div id="game_info" class="hide">
			<dl>
				<dt>User count:</dt>
				<dd id="game_info-user_count"></dd>
			</dl>
		</div>
		<div id="player_panel" class="hide">
			<h1>Player: <span id="player_name">?</span></h1>
			<div class="state_panel">
				<em>Waiting for next round...</em>
			</div>
			<div class="state_panel confirm_state hide">
				<div class="block">
					<button value="ready" class="user_action thoughtbot" />Ready</button>
				</div>
				<div class="block">
					<h2>Waiting on players to confirm:</h2>
					<div class="player_confirmations"><em>Waiting...</em></div>
				</div>
			</div>
			<div class="state_panel competition_state hide">
				<div class="block">
					<button value="answer" class="user_action fat-blue">ANSWER</button>
				</div>
				<div class="block">
					<h2>Results:</h2>
					<div class="player_results"><em>Waiting...</em></div>
				</div>
			</div>
		</div>
		<div id="admin_panel" class="hide">
			<h1>Admin</h1>
			<div class="state_panel">
				<div class="block">
					<button value="confirm" class="user_action thoughtbot">Begin</button>
				</div>
			</div>
			<div class="state_panel confirm_state hide">
				<div class="block">
					<button value="start" class="user_action thoughtbot">Start</button>
				</div>
				<div class="block">
					<h2>Waiting on players to confirm:</h2>
					<div class="player_confirmations"><em>Waiting...</em></div>
				</div>
			</div>
			<div class="state_panel competition_state hide">
				<div class="block">
					<button value="confirm" class="user_action thoughtbot">Finish</button>
				</div>
				<div class="block">
					<h2>Results:</h2>
					<div class="player_results"><em>Waiting...</em></div>
				</div>
			</div>
		</div>
		<div id="presenter_panel" class="hide">
			<div class="state_panel confirm_state hide">
				<div class="block">
					<h2>Waiting on players to confirm:</h2>
					<div class="player_confirmations"><em>Waiting...</em></div>
				</div>
			</div>
			<div class="state_panel competition_state hide">
				<div class="block">
					<h2>Results:</h2>
					<div class="player_results"><em>Waiting...</em></div>
				</div>
			</div>
		</div>
	</body>
</html>

